package org.xxpay.pay.channel.yeepay.util;

import com.cfca.util.pki.PKIException;
import com.cfca.util.pki.api.CertUtil;
import com.cfca.util.pki.api.KeyUtil;
import com.cfca.util.pki.api.SignatureUtil;
import com.cfca.util.pki.cert.X509Cert;
import com.cfca.util.pki.cipher.JCrypto;
import com.cfca.util.pki.cipher.JKey;
import com.cfca.util.pki.cipher.Session;
import org.xxpay.core.common.util.MD5Util;
import org.xxpay.core.common.util.MyLog;

public class SignUtil {

    private static final MyLog logger = MyLog.getLog(SignUtil.class);

    private static Session session = null;

    public static void initSession(){
        try {
            if(session != null) return ;
            JCrypto jcrypto = JCrypto.getInstance();
            jcrypto.initialize(JCrypto.JSOFT_LIB, null);
            session = jcrypto.openSession(JCrypto.JSOFT_LIB);
        } catch (PKIException e) {
            logger.error("initSession", e);
        }
    }

    /**
     * 对数据进行签名
     * @param signSource 签名原始串
     * @param pfxPath p12证书地址
     * @param pfxPWD 证书密码
     * @return 签名信息摘要
     */
    public static String sign(String signSource, String pfxPath, String pfxPWD){
        try{
            initSession(); //初始化session

            JKey jkey = KeyUtil.getPriKey(pfxPath, pfxPWD);
            X509Cert cert = CertUtil.getCert(pfxPath, pfxPWD);
            System.out.println(cert.getSubject());
            X509Cert[] cs=new X509Cert[1];
            cs[0]=cert;

            byte[] b64SignData;
            //对MD5签名之后数据调用CFCA提供的api方法用商户自己的数字证书进行签名
            b64SignData = new SignatureUtil().p7SignMessage(true, signSource.getBytes(), SignatureUtil.SHA1_RSA, jkey, cs, session);
            return new String(b64SignData, "UTF-8");
        }catch(Exception e){
            logger.error("signError", e);
            return null;
        }
    }

    /**
     * 验证hmac是否正确， 并返回原始签名串
     * @param hmac
     * @return 验证失败返回null
     */
    public static String verifyHMAC(String hmac){
        try{
            initSession(); //初始化session

            SignatureUtil signatureUtil = new SignatureUtil();
            boolean flag = signatureUtil.p7VerifySignMessage(hmac.getBytes(), session);//证书验
            if(!flag) { //证书验证失败
                return null;
            }
            return new String(signatureUtil.getSignedContent());

        }catch (Exception e){
            logger.error("", e);
            return null;
        }
    }


    /**
     * 生成签名原始串（拼接 + MD5）
     * @param fields 字段数据集合
     * @return
     */
    public static String genSignSource(String ... fields){

        StringBuffer str = new StringBuffer();
        for(String field : fields) {
            str = str.append(field);
        }
        return MD5Util.string2MD5(str.toString());
    }
}
